#pragma once
#include "service_registry.h"
#include <atomic>
#include <random>
#include <functional>
#include <stdexcept>

namespace cpp_backend {
namespace framework {

/**
 * @brief 负载均衡器
 * 
 * 支持多种负载均衡策略：
 * - RoundRobin: 轮询
 * - Random: 随机
 * - WeightedRandom: 加权随机
 * - ConsistentHash: 一致性哈希（粘性会话）
 */
class LoadBalancer {
public:
    enum class Strategy {
        RoundRobin,      // 轮询
        Random,          // 随机
        WeightedRandom,  // 加权随机
        ConsistentHash   // 一致性哈希（粘性会话）
    };
    
    LoadBalancer() : round_robin_index_(0) {
        // 初始化随机数生成器
        std::random_device rd;
        rng_.seed(rd());
    }
    
    /**
     * @brief 选择服务实例
     * 
     * @param instances 可用实例列表
     * @param strategy 负载均衡策略
     * @param key 一致性哈希的key（可选）
     * @return 选中的实例
     * @throws std::runtime_error 如果实例列表为空
     */
    ServiceInstance select(
        const std::vector<ServiceInstance>& instances,
        Strategy strategy = Strategy::RoundRobin,
        const std::string& key = ""
    ) {
        if (instances.empty()) {
            throw std::runtime_error("No available instances");
        }
        
        switch (strategy) {
            case Strategy::RoundRobin:
                return select_round_robin(instances);
            case Strategy::Random:
                return select_random(instances);
            case Strategy::WeightedRandom:
                return select_weighted(instances);
            case Strategy::ConsistentHash:
                return select_consistent_hash(instances, key);
            default:
                return instances[0];
        }
    }
    
private:
    std::atomic<size_t> round_robin_index_;
    std::mt19937 rng_;
    
    /**
     * @brief 轮询算法
     */
    ServiceInstance select_round_robin(const std::vector<ServiceInstance>& instances) {
        size_t index = round_robin_index_.fetch_add(1) % instances.size();
        return instances[index];
    }
    
    /**
     * @brief 随机算法
     */
    ServiceInstance select_random(const std::vector<ServiceInstance>& instances) {
        std::uniform_int_distribution<size_t> dist(0, instances.size() - 1);
        return instances[dist(rng_)];
    }
    
    /**
     * @brief 加权随机算法
     */
    ServiceInstance select_weighted(const std::vector<ServiceInstance>& instances) {
        // 计算总权重
        int total_weight = 0;
        for (const auto& inst : instances) {
            total_weight += inst.weight;
        }
        
        if (total_weight == 0) {
            return instances[0];
        }
        
        // 随机选择
        std::uniform_int_distribution<int> dist(1, total_weight);
        int random_weight = dist(rng_);
        
        int current_weight = 0;
        for (const auto& inst : instances) {
            current_weight += inst.weight;
            if (random_weight <= current_weight) {
                return inst;
            }
        }
        
        return instances[0];
    }
    
    /**
     * @brief 一致性哈希算法
     */
    ServiceInstance select_consistent_hash(
        const std::vector<ServiceInstance>& instances,
        const std::string& key
    ) {
        if (key.empty()) {
            // 如果没有key，降级为轮询
            return select_round_robin(instances);
        }
        
        // 简单的哈希实现
        size_t hash = std::hash<std::string>{}(key);
        size_t index = hash % instances.size();
        return instances[index];
    }
};

} // namespace framework
} // namespace cpp_backend
